package cn.com.nes.common.util;

import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class DESUtil {
    //算法名称 
    public static final String KEY_ALGORITHM = "DES";
    //算法名称/加密模式/填充方式 
    //DES共有四种工作模式-->>ECB：电子密码本模式、CBC：加密分组链接模式、CFB：加密反馈模式、OFB：输出反馈模式
    public static final String CIPHER_ALGORITHM = "DES/ECB/PKCS5Padding";

    /**
     *   
     * 生成密钥key对象
     * @param keyStr 密钥字符串
     * @return 密钥对象 
     * @throws InvalidKeyException   
     * @throws NoSuchAlgorithmException   
     * @throws InvalidKeySpecException   
     * @throws Exception 
     */
    private static SecretKey keyGenerator(String keyStr) throws Exception {
        byte input[] = HexString2Bytes(keyStr);
        DESKeySpec desKey = new DESKeySpec(input);
        //创建一个密匙工厂，然后用它把DESKeySpec转换成
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        SecretKey securekey = keyFactory.generateSecret(desKey);
        return securekey;
    }

    private static int parse(char c) {
        if (c >= 'a') return (c - 'a' + 10) & 0x0f;
        if (c >= 'A') return (c - 'A' + 10) & 0x0f;
        return (c - '0') & 0x0f;
    }

    // 从十六进制字符串到字节数组转换 
    public static byte[] HexString2Bytes(String hexstr) {
        byte[] b = new byte[hexstr.length() / 2];
        int j = 0;
        for (int i = 0; i < b.length; i++) {
            char c0 = hexstr.charAt(j++);
            char c1 = hexstr.charAt(j++);
            b[i] = (byte) ((parse(c0) << 4) | parse(c1));
        }
        return b;
    }

    /** 
     * 加密数据
     * @param data 待加密数据
     * @param key 密钥
     * @return 加密后的数据 
     */
    public static String encrypt(String data, String key) throws Exception {
        Key deskey = keyGenerator(key);
        // 实例化Cipher对象，它用于完成实际的加密操作
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        SecureRandom random = new SecureRandom();
        // 初始化Cipher对象，设置为加密模式
        cipher.init(Cipher.ENCRYPT_MODE, deskey, random);
        byte[] results = cipher.doFinal(data.getBytes());
        // 该部分是为了与加解密在线测试网站（http://tripledes.online-domain-tools.com/）的十六进制结果进行核对
        //for (int i = 0; i < results.length; i++) {
            //System.out.print(results[i] + " ");
        //}
        //System.out.println();
        // 执行加密操作。加密后的结果通常都会用Base64编码进行传输 
        return Base64.encodeBase64String(results);
    }

    /** 
     * 解密数据 
     * @param data 待解密数据 
     * @param key 密钥 
     * @return 解密后的数据 
     */
    public static String decrypt(String data, String key) throws Exception {
        Key deskey = keyGenerator(key);
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        //初始化Cipher对象，设置为解密模式
        cipher.init(Cipher.DECRYPT_MODE, deskey);
        // 执行解密操作
        return new String(cipher.doFinal(Base64.decodeBase64(data)));
    }

    public static Connection getDBConnect_JDBC_TEST() {
		Connection conn = null;
		 String url =
		 "jdbc:mysql://yun.nes.com.cn:3308/ctcetest?characterEncoding=utf-8";
		 String user = "ctcetest";
		 String password = "lastchgBWXY1502!";
		 try {
		// //Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
		 Class.forName("com.mysql.jdbc.Driver").newInstance();
		 } catch (InstantiationException e) {
		 e.printStackTrace();
		 } catch (IllegalAccessException e) {
		 e.printStackTrace();
		 } catch (ClassNotFoundException e) {
		 e.printStackTrace();
		 }
		 try {
		 conn = DriverManager.getConnection(url, user, password);
		 conn.setAutoCommit(false);
		 } catch (SQLException e1) {
		 e1.printStackTrace();
		 }
		return conn;
	}	
    
    public static Connection getDBConnect_JDBC() {
		Connection conn = null;
		 String url =
		 "jdbc:mysql://bjctce.nes.com.cn:3308/ctceyun?characterEncoding=utf-8";
		 String user = "ctceyun";
		 String password = "NESctce2017";
		 try {
		// //Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
		 Class.forName("com.mysql.jdbc.Driver").newInstance();
		 } catch (InstantiationException e) {
		 e.printStackTrace();
		 } catch (IllegalAccessException e) {
		 e.printStackTrace();
		 } catch (ClassNotFoundException e) {
		 e.printStackTrace();
		 }
		 try {
		 conn = DriverManager.getConnection(url, user, password);
		 conn.setAutoCommit(false);
		 } catch (SQLException e1) {
		 e1.printStackTrace();
		 }
		return conn;
	}
    
    public static void main(String[] args) throws Exception {
    	//4sW2k/ijs/OOHkVMPnxF8OkVyuP97VDf
    	//4sW2k/ijs/P3Or6CgHCM8rCXxNqmtjs0
    	
    	String encryptData = "110223198411033534" ;
    	//System.out.println("加密前: " + source);
		 encryptData = encrypt(encryptData, Globals.DESKEY);
		
		System.out.println("加密后: " + encryptData);
    	//encryptData = decrypt(encryptData, Globals.DESKEY);
		 //System.out.println("解密后: " + encryptData);
		// encryptData = decrypt(encryptData, Globals.DESKEY);
		 
		//System.out.println("解密后: " + encryptData);
		
		//encryptData = encrypt(encryptData, Globals.DESKEY);
		//System.out.println("再解密: " + encryptData);
		
		/*
    	Connection conn = null ;
    	PreparedStatement ps = null ;
    	PreparedStatement ps1 = null ;
    	ResultSet rs = null ;
    	StringBuffer sb1 = new StringBuffer();
    	int cnt = 1 ;
    	while(cnt>0){
    		try {
        		conn = getDBConnect_JDBC();
        		conn.setAutoCommit(false) ;
            	StringBuffer sb = new StringBuffer();
            	sb.delete(0, sb.length()) ;
            	sb.append(" select sfzh,sb_id from t_sbazdd where  LENGTH(sfzh)=56 ");
        		sb = DBUitl.sql_check(sb);
        		ps = conn.prepareStatement(sb.toString());
        		rs = ps.executeQuery();
        		rs.last();
        		cnt = rs.getRow();
        		
        		rs.beforeFirst() ;
        		sb1.delete(0, sb.length()) ;
        		sb1.append("update t_sbazdd set sfzh=?,byn1=1 where  sb_id=? ") ;
        		int i=0;
        		while(rs.next()){
        			String source = rs.getString(1) ;
        			String sb_id = rs.getString("sb_id") ;
        			if(source==null){
        				source = "" ;
        			}
        			String encryptData = decrypt(source, Globals.DESKEY);
        			System.out.println(encryptData);
        			ps1 = conn.prepareStatement(sb1.toString(),
        					ResultSet.TYPE_SCROLL_INSENSITIVE,
        					ResultSet.CONCUR_UPDATABLE);
        			ps1.setString(1, encryptData);
        			ps1.setString(2, sb_id);
        			int cnt2 = ps1.executeUpdate();
        			//System.out.println(cnt2);
        			i++ ;
        			if(i % 300 ==0 ){
        				System.out.println(i);
        				conn.commit() ;
        				System.out.println("committed..........");
        			}
        		}
        		//ps1.executeBatch() ;
        		conn.commit() ;
        		System.out.println("committed 5000..........");
        	}catch (Exception e) {
        		e.printStackTrace();
        		conn.rollback() ;
    		} finally {
    			if (ps1 != null) {
        			ps1.close();
    			}
        		if (ps != null) {
        			ps.close();
    			}
        		if (rs != null) {
        			rs.close();
    			}
    			if (conn != null) {
    				conn.close();
    			}
    		}
    	}
    	
    	*/
		
    	
        //String source = "身份证号后4位有误";
        //System.out.println("原文: " + source);
        //String key = Globals.DESKEY;
        
        //System.out.println("加密后: " + encryptData);
        
        //System.out.println("解密后: " + decryptData);
    }
}